#include "read.h"

#include <stdio.h>
#include <stdlib.h>
#include "definitions.h"
#include "endian.h"
#include "Config.h"

int Endian = NO_ENDIAN;

void requestCopy(PartitionedRequest * pr, Request * r){
    pr->timestamp = r->timestamp;
    pr->server =    r->server;
    pr->size =      r->size;
    pr->p_class= -1;
}

void requestCount(char *filename) {
    FILE *f;
    f = fopen(filename, "rb");
    if (!f) {
        printf("Error fopen logfile\n");
        exit(-1);
    }

    Request BER;
    int value;

    while (1) {
        value = fread(&BER, sizeof (Request), 1, f);
        if (value != 1) break;
        N_P_REQUEST++;
    }

    fclose(f);
}

int readLogFile(char *filename, int offset) {
    FILE *f = fopen(filename, "rb");
    if (!f) {
        printf("Error fopen logfile\n");
        exit(-1);
    }

    Request BER, LER, *R;
    int count = 0, value;

    /* status indicator */
    printf("Reading Access Log %s\n", filename);

    if((fread(&BER, sizeof(struct request), 1, f)) != 1)
    {
      fprintf(stderr,"Error: Failed to read initial request!\n");
      exit(0);
    }

    switch (Endian) {
        case LITTLE_ENDIAN:
        {
            LittleEndianRequest(&BER, &LER);
            R = &LER;
        }
            break;
        case BIG_ENDIAN:
        {
            R = &BER;
        }
            break;
        default:
        {
            printf("Error: unknown Endian!\n");
            exit(-1);
        }
    }
    
    requestCopy(&p_request[offset], R);

    while ((!feof(f)) && (1)) {

        count++;
        value = fread(&BER, sizeof (struct request), 1, f);

        if (value == 1) {
            switch (Endian) {
                case LITTLE_ENDIAN:
                {
                    LittleEndianRequest(&BER, &LER);
                    R = &LER;
                }
                    break;
                case BIG_ENDIAN:
                {
                    R = &BER;
                }
                    break;
                default:
                {
                    printf("Error: unknown Endian!\n");
                    exit(-1);
                }
            }
        }
        if(-1==(int)R->size)
            R->size = 0;
        requestCopy(&p_request[count+offset], R);
    }
    
    fclose(f);
    return count;
}

void readLog() {
    printf("Loading Request Log\n");
    Endian = CheckEndian();
    N_P_REQUEST = 0;

    int chk_cp_count=0;

    int i;
    for (i = 0; i < N_WC_LOG; i++) {
        requestCount(wc_log[i]);
    }

    p_request = malloc((sizeof (PartitionedRequest)) * N_P_REQUEST);
    if (p_request == NULL) {
        printf("Malloc error\n");
        exit(-1);
    }

    printf("Requests number: %lu\n", N_P_REQUEST);

    for (i = 0; i < N_WC_LOG; i++) {
        chk_cp_count += readLogFile(wc_log[i], chk_cp_count);
    }

    if(chk_cp_count!=N_P_REQUEST){
        printf("Error: Number of requests don't match\n");
    }
    printf("Loading Request Log finished\n");
}